#include "xdialog.h"
#include <stdio.h>
#include <string.h>
#include "xdialogtransaction.h"
#include "xrequest.h"
#include "xresponse.h"
#include "xheader.h"
#include "xdeepcontent.h"
#include "xtransactionstate.h"
#include "msg.h"
#include "xdialogtransactionstate.h"
#include "libxsip.h"

XSIPDialog::XSIPDialog()
{

}

XSIPDialog::~XSIPDialog()
{
	XSIPEngine::getCurrentThreadEngine()->removeDialog(this);
}

void* XSIPDialog::getObject(const char* name) const
{
	if (strcmp(name, "XSIPDialog") == 0)
		return const_cast<XSIPDialog*>(this);
	else
		return XSIPCall::getObject(name);
}

int XSIPDialog::sendAck(XSIPTransaction* transaction)
{
	XSIPTransactionState *state = transaction->getTranactionState();
	XSIPDialogTransaction* dialogTransaction = (XSIPDialogTransaction*)transaction->getObject("XSIPDialogTransaction");

	XSIPRequest* ack = dialogTransaction->getAck();
	if (ack == NULL)
	{
		ack = new XSIPRequest();
		XSIPHeader* header = new XSIPHeader();
		XSIPContent* content = new XSIPDeepContent();
		ack->setHeader(header);
		ack->setContent(content);
		dialogTransaction->setAck(ack);
		XSIPRequest* request = transaction->getRequest();
		header->addHeader(XSIP_MSG_HEADER_METHOD, "ACK");
		header->copy(request->getHeader(), XSIP_MSG_HEADER_CSEQ);
		header->copy(request->getHeader(), XSIP_MSG_HEADER_VERSION);
		header->copy(request->getHeader(), XSIP_MSG_HEADER_TRANSACTION_ID);
		header->copy(request->getHeader(), XSIP_MSG_HEADER_CALL_ID);
		header->copy(request->getHeader(), XSIP_MSG_HEADER_SESSION_ID);
	}
	state->setState(TSX_STATE_SEND_ACK);
	state->touch();
	return 0;
}

XSIPTransaction* XSIPDialog::createTransaction(XSIPRequest* request, XSIPTransport* transport)
{
	m_transaction = new XSIPDialogTransaction(XSIPTransaction::TRANSACTION_TYPE_DIALOG_OPEN);
	m_transaction->setRequest(request);
	m_transaction->setTransport(transport);
	XSIPDialogClientTransactionState *state = new XSIPDialogClientTransactionState(m_transaction);
	m_transaction->setTransactionState(state);
	state->setTransaction(m_transaction);
	request->setTransaction(m_transaction);
	XSIPEngine::getCurrentThreadEngine()->addTransaction(m_transaction);
	m_transaction->setOwner((XSIPCall*)getObject("XSIPCall"));
	XSIPHeader *header = request->getHeader();
	header->addHeader(XSIP_MSG_HEADER_TRANSACTION_ID, m_transaction->getTransactionId());
	header->addHeader(XSIP_MSG_HEADER_CALL_ID, getCallId());
	header->addHeader(XSIP_MSG_HEADER_METHOD, "INVITE");

	XSIPHeader::header dialogId;
	strcpy(dialogId.data, m_guid);
	if (!XSIPEngine::getCurrentThreadEngine()->lookupDialog(&dialogId))
	{
		XSIPEngine::getCurrentThreadEngine()->addDialog(this);
	}
	return m_transaction;
}

XSIPResponse* XSIPDialog::createResponse(XSIPTransaction* transaction, XSIPRequest* request, int code)
{
	XSIPResponse* response = XSIPCall::createResponse(transaction, request, code);
	XSIPHeader::header *callId = request->getHeader()->getHeader(XSIP_MSG_HEADER_CALL_ID);
	setCallId(callId->data);
	XSIPHeader::header dialogId;
	strcpy(dialogId.data, m_guid);
	if (!XSIPEngine::getCurrentThreadEngine()->lookupDialog(&dialogId))
	{
		XSIPEngine::getCurrentThreadEngine()->addDialog(this);
	}
	return response;
}